package blog

import (
	"encoding/json"
	"time"

	"gitee.com/go-course/go9/tree/master/projects/vblog/api/apps/tag"
	"gitee.com/go-course/go9/tree/master/projects/vblog/api/validator"
)

// 这样定义列表？比如 需要扩展 BlogList的功能的时候
// type BlogList []*Blog

func NewBlogSet() *BlogSet {
	return &BlogSet{
		Items: []*Blog{},
	}
}

// 列表, 用于分页返回的数据列表对象
type BlogSet struct {
	// 总共有多少文章
	Total int64 `json:"total"`
	// 分页请求返回的博客列表
	Items []*Blog `json:"items"`
}

func (s *BlogSet) AddItem(item *Blog) {
	s.Items = append(s.Items, item)
}

func NewBlog(req *CreateBlogRequest) *Blog {
	now := time.Now()
	return &Blog{
		CreatedAt:         now.Unix(),
		UpdatedAt:         now.Unix(),
		CreateBlogRequest: req,
		// 只需要修改一个地方
		// Meta:              map[string]string{},
	}
}

type Blog struct {
	// 文章Id
	Id int `json:"id"`
	// 创建时间(10 位的时间戳)
	CreatedAt int64 `json:"created_at"`
	// 更新时间
	UpdatedAt int64 `json:"updated_at"`
	// 发布时间
	PulishedAt int64 `json:"pulished_at"`
	// 创建参数
	*CreateBlogRequest
	// 博客的标签
	Tags []*tag.Tag `json:"tags"`
}

// 比如 fmt.Print(obj), 你希望这个对象展示成文本格式, 要怎么办
// fmt.Print("name: %s, ...", obj.Name, ...)
// 也可以 obj 实现Stringer接口: String() string, fmt.Print()
// Stringer is implemented by any value that has a String method,
// which defines the ``native'' format for that value.
// The String method is used to print values passed as an operand
// to any format that accepts a string or to an unformatted printer
// such as Print.
// type Stringer interface {
// 	String() string
// }

func (b *Blog) String() string {
	dj, err := json.Marshal(b)
	if err != nil {
		panic(err)
	}
	return string(dj)
}

// 通过构造函数构造一个请求对象
func NewCreateBlogRequest() *CreateBlogRequest {
	return &CreateBlogRequest{
		Status: DRAFT,
	}
}

// 用户创建文章传递的请求参数
type CreateBlogRequest struct {
	// 文章标题, 唯一键, 不允许重复
	Title string `json:"title" validate:"required"`
	// 文章的作者
	Author string `json:"author" validate:"required"`
	// 概要描述
	Summary string `json:"summary" validate:"required"`
	// 文章内容
	Content string `json:"content" validate:"required"`
	// 文章当前状态,枚举  草稿/已发布
	Status Status `json:"status"`
}

// 1 req.Tile req.Summary 每个字段指定写代码来进行检查, 具有很高的灵活性
// 2. 使用一些通用检查库来 判断字段的合法性, validator
func (req *CreateBlogRequest) Validate() error {
	// if req.Title == "" {
	// 	return fmt.Errorf("title requried")
	// }
	return validator.V().Struct(req)
}

// type EditBlogRequest struct {
// 	// 概要描述
// 	Summary string `json:"summary"`
// 	// 文章内容
// 	Content string `json:"content"`
// }
